//
//  main.c
//  H264toMP4
//
//  Created by iMac on 2018/9/6.
//  Copyright © 2018年 iMac. All rights reserved.
//

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#import "mp4conf.h"
#import "mp4file.h"
#import "mp4enc.h"
//#include "h264.h"

//-------------------------主函数测试-----------------------------
#if 1
#define BUFSIZE (1024 * 1024)
unsigned char buffer[BUFSIZE];
int m_nPos = 0;
int m_nPrepos = 0;
int g_nSize = 0;
int InitFirstPos(unsigned char* pData, unsigned int uiSize)
{
    while(m_nPos < uiSize - 4)
    {
        if(pData[m_nPos] == 0x00)
            if(pData[m_nPos+1] == 0x00)
                if(pData[m_nPos+2] == 0x00)
                    if(pData[m_nPos+3] == 0x01)
                        break;
        m_nPos ++;
    }
    
    m_nPrepos = m_nPos;
    return 0;
}
int open_h264(const char* fileName)
{
    FILE *fp = 0;
    int size;
    
    fp = fopen(fileName, "rb");
    if(fp == 0)
    {
        printf("Failed to open %s\n", "out.264");
        return -1;
    }
    fseek(fp, 0, SEEK_SET);
    size = fread(buffer, sizeof(unsigned char), BUFSIZE, fp);
    if(size >= BUFSIZE)
    {
        printf("File size is larger than BUFSIZE\n");
    }
    else printf("File size is smaller than BUFSIZE\n");
    
    g_nSize = size;
    
    if(!fp)
        fclose(fp);
    
    InitFirstPos(buffer, g_nSize);
    return 0;
}

uint8_t* read_nal_from_h264(uint64_t* pSize)
{
    uint8_t* pData = NULL;
    m_nPos = m_nPrepos + 4;
    while(m_nPos < g_nSize - 4)
    {
        if(buffer[m_nPos] == 0x00)
            if(buffer[m_nPos+1] == 0x00)
                if(buffer[m_nPos+2] == 0x00)
                    if(buffer[m_nPos+3] == 0x01)
                        break;
        m_nPos ++;
    }
    if(m_nPos == g_nSize - 4)
    {
        return NULL;
    }
    
    *pSize = m_nPos - (m_nPrepos/*+4*/);
    pData = (uint8_t*)malloc(*pSize);
    memset(pData, 0, *pSize);
    memcpy(pData, buffer+(m_nPrepos/*+4*/), *pSize);
    m_nPrepos = m_nPos;
    return pData;
}

int close_h264()
{
    return 0;
}

int main(){
    Mp4Context * mov=malloc(sizeof(Mp4Context));
    FILE * fp=mp4_fopen("result.mp4","wb");
    int nal_list_len=0;
    int nal_list_it=0;
    nal_list * nal_list_head=NULL;
    uint64_t size=0;
    uint64_t sum_size=0;
    uint8_t * buf=NULL;
    nal_list *one_node=NULL;
    //uint32_t max_nal=6;
    memset(mov,0,sizeof(Mp4Context));
    mov->MEDIA_SAMPLE_DURATION=MEDIA_TIMESCALE2/25;
    
    mov->mp4_fp=fp;
    mov->time=0xC6BFDE31;
    mov_write_header(mov->mp4_fp,mov);//写了Mp4的头部与mdat的头部
    open_h264("TEST-Huawei.264");
    
    while((buf=read_nal_from_h264(&size))!=NULL)
    {
        int nal_type=0;
        int buf_it=0;
        int type = 0;
        //printf("offset:%d\tsize:%x\n",sum_size,size);
        //------------------保存分析结果------------------------------
        if(size<5){                            //无法进行类型判断故不做分析
            free(buf);
            continue;
        }
        
        type = buf[4]&0x1F;
        switch (type)
        {
            case 7:                            //SPS信息
                nal_type=2;
                if(0==mov->sps_len){        //记录一次SPS
                    mov->sps_len=size-4;
                    mov->sps=malloc(mov->sps_len);
                    memcpy(mov->sps,buf+4,mov->sps_len);
                }
                
                break;
            case 8:                            //PPS信息
                nal_type=3;
                if(0==mov->pps_len){        //记录一次PPS
                    mov->pps_len=size-4;
                    mov->pps=malloc(mov->pps_len);
                    memcpy(mov->pps,buf+4,mov->pps_len);
                }
                break;
            case 5:                            //IDR帧信息
                nal_type=1;
                break;
            case 6:                            //SEI信息
                nal_type=4;
                break;
            case 1:                            //B,P帧默认为0
                nal_type=0;
                break;
            default:                        //未识别帧
                nal_type=-1;
                break;
        }
        one_node=(nal_list *)malloc(sizeof(struct nal_list));
        one_node->nal_type=nal_type;
        one_node->nal_offset=sum_size;
        one_node->nal_size=size;
        one_node->next=NULL;
        
        //one_node->nal_type!=2&&one_node->nal_type!=3&&one_node->nal_type!=4){
        if(one_node->nal_type==1||one_node->nal_type==0){
            nal_list_insert_end(one_node,mov);
            put_h264_buffer(mov->mp4_fp,buf,size);        //把数据输入mp4文件
            sum_size+=size;
        }
        //------------------------------------------------------------
        free(buf);
        buf=NULL;
    }
    close_h264();
    mov->mdat_size=sum_size;
    mov->video_track=nal_list_get_head(mov);
    //    mov->video_track_size=nal_list_get_size(mov);    //可不更新
    mov->width= 252;                                //测试264文件宽度
    mov->height= 288;                        //测试264文件高度
    
    printf("sum_nal:%d\n",mov->video_track_size);    //输出总长度
    printf("sum_size:0x%x\n",sum_size);                //输出总长度
    
    mov_write_trailer(mov->mp4_fp,mov);
    mp4_fclose(mov->mp4_fp);
    free(mov);
    return 0;
}
#endif /*main*/
